package Construibles;

import java.util.ArrayList;

import Excepciones.FueraDeLimites;
import MapaStuff.Hectarea;
import RedStuff.ClienteAgua;
import RedStuff.ClienteElectrico;
import RedStuff.ClienteVial;
import RedStuff.Conector;
import RedStuff.ConectorAgua;
import RedStuff.ConectorElectrico;
import RedStuff.ConectorVial;
import RedStuff.Red;
import RedStuff.RedAgua;
import RedStuff.RedElectrica;
import RedStuff.RedVial;
import Ubicacion.Direccion;
import Ubicacion.Este;
import Ubicacion.Norte;
import Ubicacion.Oeste;
import Ubicacion.Sur;

public abstract class ConectorUniversal extends ConstruibleFisico implements Conector{
	
	
	private abstract class Casteador{
		public abstract void castearConeccion(Hectarea hectarea,Red red,ArrayList clientes);
	}
	
	private class CasteadorElectrico extends Casteador{
		public void castearConeccion(Hectarea hectarea,Red red,ArrayList clientes){
			RedElectrica redEle=(RedElectrica) red;
			ConectorElectrico conectorDeRed=redEle.buscarConector(hectarea);
			if(sePuedeConectarAvecino(conectorDeRed)){
				conectorDeRed.conectarConVecinosYDevolverClientes(redEle, clientes);
			}
		}
	}
	
	private class CasteadorAgua extends Casteador{
		public void castearConeccion(Hectarea hectarea,Red red,ArrayList clientes){
			RedAgua redAgua=(RedAgua) red;
			ConectorAgua conectorDeRed=redAgua.buscarConector(hectarea);
			if(sePuedeConectarAvecino(conectorDeRed)){
				conectorDeRed.conectarConVecinosYDevolverClientes(redAgua, clientes);
			}
		}
	}
	
	private class CasteadorVial extends Casteador{
		public void castearConeccion(Hectarea hectarea,Red red,ArrayList clientes){
			RedVial redVial=(RedVial) red;
			ConectorVial conectorDeRed=redVial.buscarConector(hectarea);
			if(sePuedeConectarAvecino(conectorDeRed)){
				conectorDeRed.conectarConVecinosYDevolverClientes(redVial, clientes);
			}
		}
	}
	
	
	private ArrayList<Direccion> direcciones;
	private boolean estaConectandose;
	
	
	public ConectorUniversal()  {
		super();
		
		direcciones=new ArrayList<Direccion>();
		direcciones.add(new Norte());
		direcciones.add(new Sur());
		direcciones.add(new Este());
		direcciones.add(new Oeste());
		estaConectandose=false;
	}	
	
	protected  boolean sePuedeConectarAvecino(ConectorElectrico conector){
		return false;
	}
	protected  boolean sePuedeConectarAvecino(ConectorAgua conector){
		return false;
	}
	protected  boolean sePuedeConectarAvecino(ConectorVial conector){
		return false;
	}
	
	protected void conectarConVecinosYDevolverClientes(RedElectrica red,	ArrayList<ClienteElectrico> clientes,boolean esUnCliente){
		this.conectarConVecinosYDevolverClientes(red, clientes, new CasteadorElectrico(),esUnCliente);
	}
	
	protected void conectarConVecinosYDevolverClientes(RedVial red,	ArrayList<ClienteVial> clientes,boolean esUnCliente){
		this.conectarConVecinosYDevolverClientes(red, clientes, new CasteadorVial(),esUnCliente);
	}
	
	protected void conectarConVecinosYDevolverClientes(RedAgua red,	ArrayList<ClienteAgua> clientes,boolean esUnCliente){
		this.conectarConVecinosYDevolverClientes(red, clientes, new CasteadorAgua(),esUnCliente);
	}
	
	
	private void conectarConVecinosYDevolverClientes(Red red,ArrayList clientes,Casteador casteador,boolean esUnCliente) {
		
		if(estaConectandose || estaDestruido){
			return;
		}
		if(esUnCliente){
			clientes.add(this);
		}
		estaConectandose=true;
		for (Direccion direccion : this.direcciones) {
			try{
				Hectarea hectareaSig=direccion.hectareaSiguiente(this.hectarea());
				casteador.castearConeccion(hectareaSig,red,clientes);
			}catch(FueraDeLimites e){}
		}
		estaConectandose=false;
	}
	
	@Override
	public void daniadoPorGodzilla() {
		this.daniar(100);
		
	}
	

}
